/*
 * This file Copyright (c) 2015. Walle.
 * (http://www.wallellen.com). All rights reserved.
 *
 *
 * This file is dual-licensed under both the
 * Walle Agreement (WA) and the GNU General Public License.
 * You may elect to use one or the other of these licenses.
 *
 * This file is distributed in the hope that it will be
 * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
 * Redistribution, except as permitted by whichever of the GPL
 * or WA you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or
 * modify this file under the terms of the GNU General
 * Public License, Version 3, as published by the Free Software
 * Foundation.  You should have received a copy of the GNU
 * General Public License, Version 3 along with this program;
 * if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * 2. For the Walle Agreement (WA), this file
 * and the accompanying materials are made available under the
 * terms of the WA which accompanies this distribution, and
 * is available at http://www.wallellen.com/agreement.html
 *
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 */

package com.wallellen.lucene.common;

import com.wallellen.lucene.constant.IndexConf;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class IqlAnalyse implements IqlAnalyseInter {
    // WHERE(sdf,dfd=sdfsfd)ORDER_BY(dddd ASC,dddd ASC)
    private static final Logger log = LoggerFactory.getLogger(IqlAnalyse.class);

    public IqlAnalyse(String IQL, int cPage, int psize) {
        if (LUCENE_QUERY_MAXNUM == 0) {
            String para = null;
            try {
                para = IndexConf.getString("config.file.luncene_max_query_num");
                LUCENE_QUERY_MAXNUM = Integer.valueOf(para);
            } catch (Exception e) {
                log.error("系统参数LUCENE_QUERY_MAXNUM错误:" + para);
            }
        }
        iql = IQL.trim();
        if (iql.indexOf("WHERE(") >= 0) {
            String where;
            where = iql.substring(iql.indexOf("WHERE(") + "WHERE(".length(), iql.indexOf(")"));
            String[] whereArray = where.split("=");
            if (whereArray.length < 2) {
                throw new RuntimeException("where错误");
            }
            title = whereArray[0];
            value = whereArray[1];

        }
        if (iql.indexOf("ORDER_BY(") >= 0) {
            String iqlpart = iql.substring(iql.indexOf("ORDER_BY("));
            group = iqlpart.substring(iqlpart.indexOf("ORDER_BY(") + "ORDER_BY(".length(), iqlpart.indexOf(")"));
        }

        this.currentPage = cPage;
        pageSize = psize;
    }

    private String iql;
    private String title;
    private String value;
    // 排序语句
    private String group;
    // 分页语句
    private int currentPage;
    private int pageSize;
    private static int LUCENE_QUERY_MAXNUM;

    public static void main(String[] args) {
        // AloneBaseManager.instance().getParameterFace().initConfig();
        // new IqlAnalyse("WHERE(sdf,dfd=sdfsfd)ORDER_BY(dddd ASC)LIMIT(5,5)");
    }

    @Override
    public String[] getLimitTitle() {
        return title.trim().toUpperCase().split(",");
    }

    @Override
    public String getLimitValue() {
        return value.replaceAll("\\(", "").replaceAll("\\)", "");
    }

    @Override
    public int getMaxTopNum() {
        return LUCENE_QUERY_MAXNUM;
    }

    @Override
    public Sort getSortTitle() {
        // ORDER_BY(dddd:int ASC,dddd:string ASC)
        // 注意被排序的字段必须被存储索引
        Sort sort = new Sort();
        if (group == null || group.trim().length() <= 0) {
            return sort;
        }
        String[] sortstr = group.split(",");
        SortField[] fields = new SortField[sortstr.length];
        try {
            for (int i = 0; i < sortstr.length; i++) {
                String sortString = sortstr[i];
                String[] para = sortString.trim().split(" ");
                String[] para2 = para[0].trim().split(":");
                String title = para2[0].trim().toUpperCase();
                String type = para2[1].trim().toUpperCase();
                String sortType = para[1].trim().toUpperCase();
                int typeInt = 0;
                if (title == null || title.length() <= 0 || type == null || type.length() <= 0 || sortType == null
                        || sortType.length() <= 0) {
                    throw new RuntimeException("排序语句错误" + group);
                }
                if (type.equals("DOUBLE")) {
                    typeInt = SortField.DOUBLE;
                }
                if (type.equals("STRING")) {
                    typeInt = SortField.STRING;
                }
                if (type.equals("LONG")) {
                    typeInt = SortField.LONG;
                }

                fields[i] = new SortField(title, typeInt, sortType.toUpperCase().equals("DESC"));
            }
            sort.setSort(fields);
        } catch (Exception e) {
            log.error("排序条件解析错误" + e);
            throw new RuntimeException("排序语句错误" + group + "/" + e);
        }
        return sort;
    }

    @Override
    public ScoreDoc[] subDoc(ScoreDoc[] allDoc) {
        int curentSize = allDoc.length - ((currentPage - 1) * pageSize);
        if (curentSize <= 0) {
            curentSize = 0;
        }
        if (curentSize > pageSize) {
            curentSize = pageSize;
        }
        ScoreDoc[] newScore = new ScoreDoc[curentSize];
        int m = 0;
        for (int i = ((currentPage - 1) * pageSize); i < ((currentPage - 1) * pageSize) + curentSize; i++) {
            if (allDoc.length < i) {
                break;
            }
            newScore[m] = allDoc[i];
            m++;
        }
        return newScore;
    }

    @Override
    public String getIQL() {
        return iql;
    }

}
